#ifndef incl_MaterialBase_h
#define incl_MaterialBase_h

#include <vector>
#include <Eigen/Dense>
#include "InternalVariables.h"
#include "SolutionDataSolid.h"
#include <iostream>
#include "util.h"

using namespace std;


using Eigen::VectorXd;
using Eigen::MatrixXd;





class MaterialBase
{
  public:

    //member variables
    bool MIXED_ELEMENT;
    int  id, Utype;
    string  timeIntegrationScheme;
    double  rho0, Kinv, spectralRadius;
    vector<double>  matData;
    vector<double>  data_deviatoric, data_viscoelastic;
    VectorXd  td;

    SolutionDataSolid  *SolnData;

    //member functions

    MaterialBase();

    virtual ~MaterialBase();

    virtual int getMaterialTypeNameNumber()
    {  return -1; }

    void setID(int val)
    {
        id = val;
        return;
    }

    virtual  bool isFiniteStrain()
    {
        return true;
    }

    int  getUtype()
    {
        return Utype;
    }

    double  getKinv()
    {
        return Kinv;
    }

    double  getDensity()
    {
        return rho0;
    }

    vector<double>  getData()
    {
        return matData;
    }

    virtual int readData(ifstream& infile, string& line);

    virtual void printData();

    virtual  int setData(vector<double>&  datain_)
    { cout << "   'setData' is not defined for this material!\n\n"; return -1; }

    virtual double computeValue(int sss,  MatrixXd&  F)
    { cout << "   'computeValue' is not defined for this material!\n\n"; return -1; }

    virtual int computeStressAndTangent(bool tangFlag, int sss,  MatrixXd&  Fn, MatrixXd&  F, double& pres, VectorXd&  stre, MatrixXd&  Cmat)
    { cout << "   'computeStressAndTangent1' is not defined for this material!\n\n"; return -1; }

    virtual int computeStressAndTangent(bool tangFlag, int sss,  MatrixXd&  Fn, MatrixXd&  F, double& pres, VectorXd&  stre, MatrixXd&  Cmat, InternalVariables& ivar, int gp, double dt)
    { cout << "   'computeStressAndTangent2' is not defined for this material!\n\n"; return -1; }

    virtual int computeMechanicalStress(int sss,  MatrixXd&  Fn, MatrixXd&  F, double& pres, VectorXd&  stre, InternalVariables& ivar, int gp, double dt)
    { cout << "   'computeMechanicalStress' is not defined for this material!\n\n"; return -1; }
};

#endif

